﻿#Requires AutoHotkey v2.0

class Tip {
    ; debounce
    static timer := false
    static pool := Map()

    __New(text, weight := 1, x := unset, y := unset) {
        MouseGetPos(&mx, &my)
        IsSet(x) || x := mx
        IsSet(y) || y := my
        if weight < 1 or weight > 20
            throw Error('invalid weight')
        if Tip.pool.Has(weight) {
            index := 1
            while Tip.pool.Has(index)
                index++
            if index > 20
                throw Error('no available tooltip')
            weight := index
        }
        ; store
        this.text := text
        this.x := x
        this.y := y
        this.weight := weight
        Tip.pool.Set(weight, true)
        return this
    }

    Display() {
        ToolTip this.text, this.x, this.y, this.weight
        return this
    }

    Recycle() {
        Tip.pool.Delete(this.weight)
        ToolTip , , , this.weight
    }

    ; display tooltip and clear after the specified seconds
    static ShowTip(raw, x := 100, y := 50, weight := 1, duration := 4000) {
        ToolTip raw, x, y, weight
        Tip.SetTimerRemoveToolTip(weight, duration)
    }

    ; remove the specified weight after some time
    static SetTimerRemoveToolTip(weight := 1, time := 4000) {
        if Tip.timer {
            ; clear prior timer
            SetTimer Tip.timer, 0
        }
        ; bind the timer
        Tip.timer := ObjBindMethod(this, 'RemoveToolTip', weight)
        ; start new timer
        SetTimer Tip.timer, -time
        ; reset after 'time'
        clear := () => Tip.timer := false
        SetTimer clear, -time
    }

    static RemoveToolTip(weight)
    {
        ToolTip , , , weight
    }
}

if A_LineFile == A_ScriptFullPath {
    Tip('tip1').Display()
    Tip('tip2').Display().Recycle()
    Tip('tip3').Display()
    Tip('tip4').Display()

}